package com.piggy.auth.services;

import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.piggy.auth.bo.OAuthReq;
import com.piggy.auth.bo.OAuthReqPwd;
import com.piggy.auth.bo.OAuthRes;
import com.piggy.common.core.constant.BizConstants;
import com.piggy.common.core.constant.SecurityConstants;
import com.piggy.common.core.domain.R;
import com.piggy.common.core.exception.base.BaseException;
import com.piggy.common.core.utils.FeignResultUtils;
import com.piggy.common.core.utils.RegexUtils;
import com.piggy.common.satoken.constants.SaTokenConst;
import com.piggy.common.satoken.enums.DeviceType;
import com.piggy.common.satoken.helper.LoginHelper;
import com.piggy.common.satoken.utils.SecurityUtils;
import com.piggy.logi.sys.api.domain.LogiSysUser;
import com.piggy.sys.api.RemoteClientService;
import com.piggy.sys.api.RemoteUserService;
import com.piggy.sys.api.domain.SysClientDetails;
import com.piggy.sys.api.domain.SysUser;
import com.piggy.sys.api.model.LoginUser;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Slf4j
@Service
@RequiredArgsConstructor
public class SysLoginService {

    @Resource
    private RemoteUserService userService;

    @Resource
    private RemoteClientService clientService;

    public OAuthRes login(OAuthReqPwd oauth) {

        R<SysClientDetails> clientDetailsR = clientService.getClientDetailsById(oauth.getClientId(), SecurityConstants.INNER);
        FeignResultUtils.throwIfFailed(clientDetailsR);
        SysClientDetails clientDetails = clientDetailsR.getData();

        if (!SecurityUtils.matchesPassword(oauth.getClientSecret(), clientDetails.getClientSecret())) {
            throw new BaseException("无效客户端");
        }

        // 此处可根据登录用户的数据不同 自行创建 loginUser
        R<LoginUser<SysUser>> userR = null;
        if (RegexUtils.isMobile(oauth.getPhone())) {
            userR = userService.getUserByPhone(oauth.getPhone(), SecurityConstants.INNER);
            FeignResultUtils.throwIfFailed(userR);
        }
        else if (RegexUtils.isEmail(oauth.getEmail())) {
            userR = userService.getUserByEmail(oauth.getEmail(), SecurityConstants.INNER);
            FeignResultUtils.throwIfFailed(userR);
        } else {
            userR = userService.getUserInfo(oauth.getUserName(), SecurityConstants.INNER);
            FeignResultUtils.throwIfFailed(userR);
        }

        SysUser user = userR.getData().getSysUser();
        String password = user.getPassword();
        if (!SecurityUtils.matchesPassword(oauth.getPassword(), password)) {
            throw new BaseException("密码错误");
        }

        LoginUser<SysUser> loginUser = userR.getData();
        loginUser.setClientDetails(clientDetails);
        loginUser.setUserName(loginUser.getSysUser().getUserName());
        loginUser.setPhone(loginUser.getSysUser().getPhonenumber());
        loginUser.setUserId(loginUser.getSysUser().getUserId());
        loginUser.setTClass(SysUser.class);
        loginUser.setBiz(BizConstants.BOSS);
        // 生成token
        LoginHelper.loginByDevice(loginUser, user.getSessionTimeout(), DeviceType.getByCode(oauth.getDeviceType()));

        return new OAuthRes()
                .setTokenType(SaTokenConst.BEARER)
                .setAccessToken(StpUtil.getTokenValue());

    }

    public boolean logout() {
        try {
            StpUtil.logout();
        } catch (NotLoginException e) {
            return true;
        } catch (Exception e) {
            log.error(e.getMessage());
            return true;
        }
        return true;
    }

    public Boolean kickout(OAuthReq oauth) {

        Long loginId = StpUtil.getLoginIdAsLong();

        if (ObjectUtil.isNotNull(loginId) && StrUtil.isNotBlank(oauth.getDeviceType())) {
            StpUtil.kickout(loginId, oauth.getDeviceType());
            return true;
        }

        if (ObjectUtil.isNotNull(loginId)) {
            StpUtil.kickout(loginId);
            return true;
        }

        StpUtil.kickoutByTokenValue(StpUtil.getTokenValue());
        return true;

    }

}
